package org.example.mock;

import com.github.javafaker.Faker;
import org.example.bean.MemberInfo;

import java.sql.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

public class MemberInfoDataGenerator {
    private static final String DB_URL = "jdbc:mysql://hadoop102/bookstore?useSSL=false&requireSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC";
    private static final String DB_USER = "root";
    private static final String DB_PASSWORD = "000000";
    private static final int BATCH_SIZE = 100;
    private static final Faker faker = new Faker(Locale.CHINA);
    private static final String[] STORE_IDS = {"S1001", "S1002", "S1003", "S1004", "S1005"};

    public static void main(String[] args) {
        int count = 1000; // 默认生成200条数据
        if (args.length >= 1) count = Integer.parseInt(args[0]);
        generateData(count);
    }

    public static void generateData(int count) {
        List<MemberInfo> members = new ArrayList<>();

        for (int i = 0; i < count; i++) {
            LocalDateTime now = LocalDateTime.now();
            LocalDate registerDate = LocalDate.now().minusMonths(faker.number().numberBetween(1, 24));

            MemberInfo member = MemberInfo.builder()
                    .memberId("M" + String.format("%08d", faker.number().numberBetween(10000000, 99999999)))
                    .memberName(faker.name().fullName())
                    .gender(faker.number().numberBetween(0, 2))
                    .birthDate(LocalDate.now().minusYears(faker.number().numberBetween(18, 70)))
                    .phone(generateValidPhoneNumber())
                    .email(faker.internet().emailAddress())
                    .registerDate(registerDate)
                    .registerStore(STORE_IDS[faker.random().nextInt(STORE_IDS.length)])
                    .memberLevel(faker.number().numberBetween(1, 4))
                    .totalPoints(faker.number().numberBetween(100, 10000))
                    .availablePoints(faker.number().numberBetween(50, 5000))
                    .lastConsumeDate(registerDate.plusDays(faker.number().numberBetween(1, 180)))
                    .createTime(now)
                    .updateTime(now)
                    .build();
            members.add(member);
        }

        insertData(members);
    }

    private static String generateValidPhoneNumber() {
        String[] prefixes = {"130", "131", "132", "133", "134", "135", "136", "137", "138", "139",
                "150", "151", "152", "153", "155", "156", "157", "158", "159",
                "170", "171", "172", "173", "175", "176", "177", "178",
                "180", "181", "182", "183", "184", "185", "186", "187", "188", "189"};
        return prefixes[faker.random().nextInt(prefixes.length)] +
                String.format("%08d", faker.number().numberBetween(0, 99999999));
    }

    private static void insertData(List<MemberInfo> members) {
        String sql = "INSERT INTO member_info (member_id, member_name, gender, birth_date, phone, " +
                "email, register_date, register_store, member_level, total_points, " +
                "available_points, last_consume_date, create_time, update_time) " +
                "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";

        try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD)) {
            conn.setAutoCommit(false);
            try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
                for (int i = 0; i < members.size(); i++) {
                    MemberInfo member = members.get(i);
                    pstmt.setString(1, member.getMemberId());
                    pstmt.setString(2, member.getMemberName());
                    pstmt.setInt(3, member.getGender());
                    pstmt.setDate(4, Date.valueOf(member.getBirthDate()));
                    pstmt.setString(5, member.getPhone());
                    pstmt.setString(6, member.getEmail());
                    pstmt.setDate(7, Date.valueOf(member.getRegisterDate()));
                    pstmt.setString(8, member.getRegisterStore());
                    pstmt.setInt(9, member.getMemberLevel());
                    pstmt.setInt(10, member.getTotalPoints());
                    pstmt.setInt(11, member.getAvailablePoints());
                    pstmt.setDate(12, Date.valueOf(member.getLastConsumeDate()));
                    pstmt.setTimestamp(13, Timestamp.valueOf(member.getCreateTime()));
                    pstmt.setTimestamp(14, Timestamp.valueOf(member.getUpdateTime()));
                    pstmt.addBatch();

                    if ((i + 1) % BATCH_SIZE == 0) pstmt.executeBatch();
                }
                pstmt.executeBatch();
                conn.commit();
                System.out.println("成功插入" + members.size() + "条会员数据");
            } catch (SQLException e) {
                conn.rollback();
                e.printStackTrace();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}